package cn.bonoon.handler.impl;

import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.Properties;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import cn.bonoon.core.plugins.ServerService;
import cn.bonoon.handler.IHardware;
import cn.bonoon.kernel.util.MD5Util;
import cn.bonoon.kernel.util.StringHelper;
import cn.bonoon.util.ServerUtil;

/**
 * <pre>
 * 服务器监控，用来监控当前服务器运行的情况
 * 提示：hyperic-sigar-1.6.4\sigar-bin\lib\sigar-x86-winnt.dll 复制到 jdk bin目录下(e.g. C:\Program Files\Java\jdk1.7.0_67\bin)
 * </pre>
 * 
 * @author jackson
 * 
 */
public class StandardServerMonitor implements InitializingBean {

	private final ServerService serverService;

	private IHardware hardware;
	/**
	 * <pre>
	 * 如何认为是相同的一台服务器：
	 * 根据CPU、MAC地址等来计算
	 * </pre>
	 */
	private final static String serverKey;

	static {
		// 当前服务器唯一的值；如果服务器退出再启动，则该值改变，而且当服务器运行过程，该值保持不变
		serverKey = MD5Util.randomMD5String();
	}

	@Autowired
	public StandardServerMonitor(ServerService serverService) {
		this.serverService = serverService;
	}

	// 第一次执行
	@Override
	public void afterPropertiesSet() throws Exception {
//		try {
//			hardware = new SigarHardware();
//			hardware.cpu();
//		} catch (Throwable t) {
			hardware = IHardware.EMPTY;
//		}
		String server = ServerUtil.getServerId();
		if (StringHelper.isEmpty(server)) {
			server = "未知服务器";
		}
		serverService.refreshServer(serverKey, __serverIP(), __osInfo(), __jvmInfo(), server, 
				hardware.cpu(), hardware.memory(), hardware.hardDisk(), hardware.otherHardware());
	}

	/**
	 * 执行监控的函数
	 * 
	 * @throws SigarException
	 */
	public void monitor() throws Exception {
		String server = ServerUtil.getServerId();
		if (StringHelper.isEmpty(server)) {
			server = "未知服务器";
		}
		serverService.refreshServer(serverKey, __serverIP(), __osInfo(), __jvmInfo(), server, 
				hardware.cpu(), hardware.memory(), hardware.hardDisk(), hardware.otherHardware());
	}

	private String __serverIP() {
		String ips = "";
		try {
			Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces();
			while (nis.hasMoreElements()) {
				NetworkInterface ni = (NetworkInterface) nis.nextElement();
				Enumeration<InetAddress> ias = ni.getInetAddresses();
				while (ias.hasMoreElements()) {
					InetAddress ia = (InetAddress) ias.nextElement();
					if (ia.isSiteLocalAddress()) {
						String hostAddress = ia.getHostAddress();
						if ((ia instanceof Inet4Address && !hostAddress.equals("127.0.0.1"))
								|| (ia instanceof Inet6Address && !hostAddress.equals(""))) {
							if (StringHelper.isEmpty(ips)) {
								ips = hostAddress;
							} else {
								ips += "," + hostAddress;
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ips;
	}

	private String __osInfo() {
		Properties props = System.getProperties();
		String osInfo = props.getProperty("os.name") + " ";
		osInfo += props.getProperty("os.arch") + " ";
		osInfo += props.getProperty("os.version");
		return osInfo;
	}

	private String __jvmInfo() {
		Properties props = System.getProperties();
		return props.getProperty("java.version");
	}

}
